/*
 * JHeuristics - The Java Meta-Heuritics Library
 * Copyright (C) 2004-2005, Universidade Federal de Campina Grande. All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.jheuristics.ga.operators.selectors;

import java.io.Serializable;
import java.util.Iterator;

import org.epanetgrid.otimizacao.log.AGLogger;
import org.epanetgrid.otimizacao.util.OtimizacaoUtil;
import org.jheuristics.Individual;
import org.jheuristics.ga.DefaultPopulation;
import org.jheuristics.ga.GAConfig;
import org.jheuristics.ga.GAStatus;
import org.jheuristics.ga.Population;
import org.jheuristics.ga.operators.Selector;


/**
 * TODO
 *
 * @author Marcell Manfrin, marcell@ourgrid.org, Jan 9, 2006
 */
public class BestIndividualsSelector implements Selector, Serializable {

	private AGLogger logger = AGLogger.getInstance();
	
    /**
     * TODO
     *
     * @param population
     * @param howMany
     * @param status
     * @param config
     * @return
     * @see org.jheuristics.ga.operators.Selector#select(org.jheuristics.ga.Population, int, org.jheuristics.ga.GAStatus, org.jheuristics.ga.GAConfig)
     */
    public Individual[] select(Population population, int howMany, GAStatus status, GAConfig config) {
        if (null == population) {
			// TODO: ERROR MSG
			throw new NullPointerException();
		}
		if (0 > howMany || population.size() < howMany) {
			// TODO: ERROR MSG
			throw new IllegalArgumentException();
		}
		
		StringBuffer buffer = new StringBuffer();
		
		buffer.append("Selecionando os ");
		buffer.append(howMany);
		buffer.append(" melhores indivíduos:\n");

		if(howMany > 0) {
			Individual[] pop = choose(sortPopulation(population), howMany).toIndividualArray();
			
			if(logger.isSelected(AGLogger.DEBUG)) {
//				for (Individual individual : pop) {
//					buffer.append(individual);
//					buffer.append(" ");
//					buffer.append(individual.getDataApplication() == null? "": individual.getDataApplication());
//					buffer.append("\n");
//				}
				buffer.append(OtimizacaoUtil.format(pop));
				logger.debug(buffer);
			}
			
			return pop;
		}else {
			buffer.append(new Individual[0]);
			logger.debug(buffer);
			return new Individual[0];
		}
		
//        return (howMany > 0) ? choose(sortPopulation(population), howMany).toIndividualArray() : new Individual[0];
    }
    
    /**
     * TODO
     *
     * @param population
     * @return
     */
    protected Population sortPopulation(Population population) {
    	Population sorted = new DefaultPopulation();
    	sorted.addIndividuals(population);
    	sorted.sort();
    	return sorted;
    }
    
    /**
     * TODO
     *
     * @param population
     * @param howMany
     * @return
     */
    protected Population choose(Population population, int howMany) {
		DefaultPopulation result = new DefaultPopulation();
		if (howMany > 0) {
			Iterator it = population.iterator();
			for(int i = 0; i < howMany; i++) {
			    result.addIndividual((Individual) it.next());
			}
		}
		result.sort();
		return result;
    }

}
